package com.czl.module_base.activity;

import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import androidx.annotation.Nullable;
import androidx.databinding.ViewDataBinding;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewbinding.ViewBinding;

import com.blankj.utilcode.util.ScreenUtils;
import com.blankj.utilcode.util.SizeUtils;
import com.chad.library.adapter.base.listener.OnItemClickListener;
import com.czl.base.base.BaseRxActivity;
import com.czl.base.callback.ErrorCallback;
import com.czl.base.callback.LoadingCallback;
import com.czl.base.util.ToastHelper;
import com.czl.module_base.R;
import com.czl.module_base.adapter.StringAdapter;
import com.czl.module_base.databinding.LayoutToolbarBinding;
import com.czl.module_base.http.HttpResponse;
import com.czl.module_base.mvp.model.IModel;
import com.czl.module_base.mvp.presenter.BasePresenter;
import com.czl.module_base.mvp.presenter.InjectPresenter;
import com.czl.module_base.mvp.view.IView;
import com.czl.module_base.mvp.view.SimpleView;
import com.czl.module_base.utils.PopWindowUtils;
import com.kingja.loadsir.callback.Callback;
import com.kingja.loadsir.callback.SuccessCallback;
import com.kingja.loadsir.core.LoadService;
import com.kingja.loadsir.core.LoadSir;
import com.lxj.xpopup.XPopup;
import com.lxj.xpopup.core.BasePopupView;
import com.lxj.xpopup.interfaces.SimpleCallback;

import org.greenrobot.eventbus.EventBus;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * @author by xubin,
 * @date on 2022/1/24.
 * PS: Not easy to write code, please indicate.
 */
public abstract class BaseActivity<V extends ViewBinding> extends BaseRxActivity implements SimpleView, View.OnClickListener {
    protected final String TAG = this.getClass().getSimpleName();
    protected LoadService<?> loadService;

    protected V binding;
    protected LayoutToolbarBinding mToolBinding;

    private List<BasePresenter<? extends IModel, ? extends IView>> mInjectPresenters;

    private BasePopupView dialog = null;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = getBinding(getLayoutInflater());
        setContentView(binding.getRoot());
        initPresenter();
        initData(savedInstanceState);
        loadData();
    }

    @Override
    public void setContentView(View view) {
        if (addToolBar()) {
            LinearLayout parent = new LinearLayout(this);
            parent.setOrientation(LinearLayout.VERTICAL);
            mToolBinding = LayoutToolbarBinding.inflate(getLayoutInflater(), parent, true);
            mToolBinding.ivBack.setOnClickListener(v -> finish());
            parent.addView(view);
            LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams();
            layoutParams.weight = 1;
            view.setLayoutParams(layoutParams);
            ViewGroup viewGroup = findViewById(android.R.id.content);
            viewGroup.removeAllViews();
            viewGroup.addView(parent);
            super.setContentView(parent);
        } else {
            super.setContentView(view);
        }
    }

    /**
     * 获取布局
     *
     * @param layoutInflater 解析器
     * @return ViewBinding
     */
    protected abstract V getBinding(LayoutInflater layoutInflater);

    protected void initData(Bundle savedInstanceState) {

    }

    protected boolean addToolBar() {
        return true;
    }

    void initPresenter() {
        mInjectPresenters = new ArrayList<>();
        //获得已经申明的变量，包括私有的
        Field[] fields = this.getClass().getDeclaredFields();
        for (Field field : fields) {
            //获取变量上面的注解类型
            InjectPresenter injectPresenter = field.getAnnotation(InjectPresenter.class);
            if (injectPresenter != null) {
                try {
                    Class<? extends BasePresenter<? extends IModel, ? extends IView>> type = (Class<? extends BasePresenter<?, ?>>) field.getType();
                    BasePresenter<? extends IModel, ? extends IView> mInjectPresenter = type.newInstance();
                    mInjectPresenter.onStart(this);
                    field.setAccessible(true);
                    field.set(this, mInjectPresenter);
                    mInjectPresenters.add(mInjectPresenter);
                } catch (IllegalAccessException | InstantiationException e) {
                    e.printStackTrace();
                } catch (ClassCastException e) {
                    e.printStackTrace();
                    throw new RuntimeException("SubClass must extends Class:BasePresenter");
                }
            }
        }
    }

    private void createLoadService() {
        if (null == loadService) {
            LoadSir loadSir = new LoadSir.Builder()
                    .addCallback(new ErrorCallback())
                    .addCallback(new LoadingCallback())
                    .setDefaultCallback(SuccessCallback.class)
                    .build();
            if (null != getLoadView()) {
                loadService = loadSir.register(getLoadView(), (Callback.OnReloadListener) v -> onReload());
            } else {
                loadService = loadSir.register(binding.getRoot(), (Callback.OnReloadListener) v -> onReload());
            }
        }
    }

    protected View getLoadView() {
        return null;
    }

    /**
     * 重新加载数据
     */
    protected void onReload() {
        loadData();
    }

    protected void loadData() {

    }

    @Override
    public void onClick(View view) {

    }

    @Override
    public void showDialogLoading(String title) {
        if (TextUtils.isEmpty(title)) {
            title = "加载中";
        }
        if (dialog == null) {
            dialog = new XPopup.Builder(getContext())
                    .setPopupCallback(new SimpleCallback() {
                        @Override
                        public void onDismiss(BasePopupView popupView) {
                            super.onDismiss(popupView);
                            if (mInjectPresenters != null && !mInjectPresenters.isEmpty()) {
                                for (BasePresenter<?, ?> presenter : mInjectPresenters) {
                                    presenter.unDispose();
                                }
                            }
                        }
                    })
                    .asLoading(title, R.layout.common_loading_dialog);
        }
        if (!dialog.isShow()) {
            dialog.show();
        }
    }

    @Override
    public void showLoading() {
        runOnUiThread(() -> {
            createLoadService();
            loadService.showCallback(LoadingCallback.class);
        });
    }

    @Override
    public void hideDialogLoading() {
        if (dialog != null && dialog.isShow()) {
            dialog.dismiss();
        }
    }

    @Override
    public void showLoadSuccess() {
        loadService.showSuccess();
    }

    @Override
    public void showEmpty() {
    }

    @Override
    public <T> void showData(T t) {

    }

    @Override
    public <T> void showHttpResponse(HttpResponse<T> httpResponse) {

    }

    @Override
    public void showError(String error) {
        if (loadService != null) {
            loadService.showCallback(ErrorCallback.class);
        }
    }

    @Override
    public void showUnKnowError(String msg, int drawable) {

    }

    protected void showToast(String msg) {
        ToastHelper.INSTANCE.showNormalToast(msg);
    }

    @Override
    public Context getContext() {
        return this;
    }

    protected void showRecyclerViewPopupWindow(List<String> list, String title, OnItemClickListener onItemClickListener) {

        View view = View.inflate(getContext(), R.layout.common_recycler_view, null);

        RecyclerView recyclerView = view.findViewById(R.id.rv_item);
        StringAdapter superAdapter = new StringAdapter(R.layout.item_select_type, list);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        recyclerView.setAdapter(superAdapter);
        superAdapter.setOnItemClickListener((adapter, view1, position) -> {
            PopWindowUtils.getInstance().dismissPopupWindow();
            onItemClickListener.onItemClick(superAdapter, view1, position);
        });
        if (list.size() > 6) {
            int width = ScreenUtils.getScreenWidth() - 2 * SizeUtils.dp2px(15);
            int height = (int) (ScreenUtils.getScreenHeight() * 0.6f);
            PopWindowUtils.getInstance().createPopWindow(getContext(), view, width, height, title);
        } else {
            int width = ScreenUtils.getScreenWidth() - 2 * SizeUtils.dp2px(15);
            PopWindowUtils.getInstance().createPopWindow(getContext(), view, width, title);
        }
        PopWindowUtils.getInstance().showBasePopupWindow(binding.getRoot());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().removeAllStickyEvents();
            EventBus.getDefault().unregister(this);
        }
        if (mToolBinding != null) {
            mToolBinding.unbind();
        }
        if (binding instanceof ViewDataBinding) {
            ((ViewDataBinding) binding).unbind();
        }
        if (mInjectPresenters != null && !mInjectPresenters.isEmpty()) {
            for (BasePresenter<?, ?> presenter : mInjectPresenters) {
                presenter.onDestroy();
            }
            mInjectPresenters.clear();
        }
        mInjectPresenters = null;
    }
}
